#include "hal.h"
#include "timers.h"
#include "terminal.h"
#include "cilindrica.h"

volatile struct_TimerSysTick TimerSysTick={0,0};

/**********************************************************************************
 * Descrição:
 *
 * Paramêtro(s):
 *					-
 * Retorno:
 *					-
 **********************************************************************************/

void timers_init(uint8_t timer_x, uint16_t periodo)
{
        TIM_TIMERCFG_Type TIM_ConfigStruct;
        TIM_MATCHCFG_Type TIM_MatchConfigStruct;

        // Inicializa o timer com a contagem de 1000us
	TIM_ConfigStruct.PrescaleOption = TIM_PRESCALE_USVAL;
	TIM_ConfigStruct.PrescaleValue	= 1000;

	if(timer_x==0)
		TIM_Init(LPC_TIM0, TIM_TIMER_MODE,&TIM_ConfigStruct);
	else if(timer_x==1)
		TIM_Init(LPC_TIM1, TIM_TIMER_MODE,&TIM_ConfigStruct);
	else if(timer_x==2)
		TIM_Init(LPC_TIM2, TIM_TIMER_MODE,&TIM_ConfigStruct);
	else if(timer_x==3)
		TIM_Init(LPC_TIM3, TIM_TIMER_MODE,&TIM_ConfigStruct);
	else
	return ;

    TIM_MatchConfigStruct.MatchChannel = 0;
	// Habilita interrupcao quando o MR0
	TIM_MatchConfigStruct.IntOnMatch   = TRUE;
	//Habilita o reset de MMR0
	TIM_MatchConfigStruct.ResetOnMatch = TRUE;
	//Stop do MR0
	TIM_MatchConfigStruct.StopOnMatch  = FALSE;
	//Modo alternado com MR0
	TIM_MatchConfigStruct.ExtMatchOutputType = TIM_EXTMATCH_TOGGLE;
	// Defini o valor a ser comparado pelo MR0
	TIM_MatchConfigStruct.MatchValue   = periodo;
        if(timer_x==0)
        {
          // Set configuration for Tim_MatchConfig
          TIM_ConfigMatch(LPC_TIM0,&TIM_MatchConfigStruct);
          /* preemption = 1, sub-priority = 1 */
          NVIC_SetPriority(TIMER0_IRQn, ((0x01<<3)|0x01));
          /* Habilita a interrup�ao do TIMER0 */
          NVIC_EnableIRQ(TIMER0_IRQn);
          //Start no timer0
          TIM_Cmd(LPC_TIM0,ENABLE);
        }
        else if(timer_x==1)
        {
          // Set configuration for Tim_MatchConfig
          TIM_ConfigMatch(LPC_TIM1,&TIM_MatchConfigStruct);
          /* preemption = 1, sub-priority = 1 */
          NVIC_SetPriority(TIMER1_IRQn, ((0x01<<3)|0x01));
          /* Habilita a interrup�ao do TIMER1 */
          NVIC_EnableIRQ(TIMER1_IRQn);
          //Start no timer1
          TIM_Cmd(LPC_TIM1,ENABLE);
        }
        else if(timer_x==2)
        {
          // Set configuration for Tim_MatchConfig
          TIM_ConfigMatch(LPC_TIM2,&TIM_MatchConfigStruct);
          /* preemption = 1, sub-priority = 1 */
          NVIC_SetPriority(TIMER2_IRQn, ((0x01<<3)|0x01));
          /* Habilita a interrup�ao do TIMER2 */
          NVIC_EnableIRQ(TIMER2_IRQn);
          //Start no timer2
          TIM_Cmd(LPC_TIM2,ENABLE);
        }
        else if(timer_x==3)
        {
          // Set configuration for Tim_MatchConfig
          TIM_ConfigMatch(LPC_TIM3,&TIM_MatchConfigStruct);
          /* preemption = 1, sub-priority = 1 */
          NVIC_SetPriority(TIMER3_IRQn, ((0x01<<3)|0x01));
          /* Habilita a interrup�ao do TIMER3 */
          NVIC_EnableIRQ(TIMER3_IRQn);
          //Start no timer3
          TIM_Cmd(LPC_TIM3,ENABLE);
        }
}

/**********************************************************************************
 * Descrição:
 *
 * Paramêtro(s):
 *					-
 * Retorno:
 *					-
 **********************************************************************************/

void timer_init(void)
{
        //Timer do systick ser� utilizado para timeouts e delays
        SYSTICK_InternalInit(1);//configura o Systick para 1ms
        SYSTICK_IntCmd(ENABLE);	//Habilita a interrupcao do systick
        SYSTICK_Cmd(ENABLE);    //habilita o contador do SYSTICK

        timers_init(0,1);  // leitura dos sensores de posiçao
        timers_init(1,30); // leitura da UART para o teclado
}

/**********************************************************************************
 * Descrição:
 *
 * Paramêtro(s):
 *					-
 * Retorno:
 *					-
 **********************************************************************************/

void delay_ms(uint32_t ms){
	TimerSysTick.TimerDelay=ms;
	while(TimerSysTick.TimerDelay);
}
/**********************************************************************************
 * Descrição:
 *
 * Paramêtro(s):
 *					-
 * Retorno:
 *					-
 **********************************************************************************/

void  timer_isr(void)
{
	int i;

	if(TimerSysTick.TimerDelay)
	{
		TimerSysTick.TimerDelay--;
	}
	//Timer de espera entre processos
	if(TimerSysTick.TimerEspera){
		TimerSysTick.TimerEspera--;
	}


	Timer1ms[0]++;
	if(Timer1ms[0] > 9)
	{
		Timer1ms[0] = 0;
		Timer10ms[0]++;
		for (i = 1; i < NUMTMR10MS; i++)
		{
			if(Timer10ms[i] > 0)
			{
				Timer10ms[i]--;
			}
		}
	}	
}


/**********************************************************************************
 * Descrição:T
 *
 * Paramêtro(s):
 *					-
 * Retorno:
 *					-
 **********************************************************************************/

void SysTick_Handler(void)
{
	timer_isr();
        //Clear System Tick counter flag
	SYSTICK_ClearCounterFlag();
}


/**********************************************************************************
 * Descrição:
 *
 * Paramêtro(s):
 *					-
 * Retorno:
 *					-
 **********************************************************************************/
void TIMER0_IRQHandler(void){
	extern Controle gControleCilindrica;
	static uint8_t timer_read_terminal=0;

	if (TIM_GetIntStatus(LPC_TIM0,TIM_MR0_INT))
	{
		sensors_isr_read();
		if((gControleCilindrica.TempoOperacao)	&&	(gControleCilindrica.Ativo))
		{
			gControleCilindrica.TempoOperacao--;
		}
		
		//timer_read_terminal++;
		//if(timer_read_terminal>50){
		//        timer_read_terminal=0;
		//isr_terminal();
		//}
		TIM_ClearIntPending(LPC_TIM0,TIM_MR0_INT);
	}
}

/**********************************************************************************
 * Descricao:
 *
 * Parametro(s):
 *					-
 * Retorno:
 *					-
 **********************************************************************************/
void TIMER1_IRQHandler(void){
  extern uint8_t  gTerminalFeedBack;

	if (TIM_GetIntStatus(LPC_TIM1,TIM_MR0_INT))
	{
		TIM_ClearIntPending(LPC_TIM1,TIM_MR0_INT);


		if(gTerminalFeedBack){
			//terminal_feedback();
		}
	}
}
